package disco;

import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

public class CFQQueue {
    int n = 0;
    
    int prioridad;          //de 0 a 7 prioridad RT
                            //de 8 a 15 prioridad BE
                            //16 Idle
                            
    private TreeMap listaCFQRequest;
    int slice;              //El time slice dedicado a esta petición
    int sliceIdle;          //TODO creo que no es necesario
    private int count = 0;
    Iterator cola;
    int numPistas;
    
    public CFQQueue(int prioridad, int sliceBase, int numPistas) {
        this.listaCFQRequest = new TreeMap();
        this.prioridad = prioridad;
        this.slice = sliceBase + 
                (CFQ.diferenciaSlice * (CFQ.numPrioridades - prioridad));
        this.numPistas = numPistas;
        cola = listaCFQRequest.values().iterator();
    }

    public synchronized CFQRequest get() {       
        while (listaCFQRequest.size() <= 0) {
            //try {
//                System.out.println("Esperando");
                return null;
                //wait();                
            //} catch (InterruptedException e) {
            //}
        }
        count --;
        //CFQRequest cFQRequest = null;
        //try {        
        //cola = listaCFQRequest.values().iterator();
       
            //cFQRequest = (CFQRequest) cola.next();   
            //int clave[] = new int[2];
            //clave[0] = cFQRequest.bloque;
           // clave[1] = cFQRequest.hashCode();
            
            //String str = "" + cFQRequest.bloque + "/" + cFQRequest.hashCode();
            
           // listaCFQRequest.remove(cFQRequest.getKey()); 
            //System.out.append("Quitado " + cFQRequest); 
        //} catch (ConcurrentModificationException e) {
            //System.out.println("fdfd " + e.getMessage());
        //}
//        CFQ.n2++;
//        System.out.println("Obtiene" +  CFQ.n2);
        Iterator itr = listaCFQRequest.entrySet().iterator();
        Entry entry;
        CFQRequestKey key = null;
        int min = Integer.MAX_VALUE;
        CFQRequestKey auxKey = null;        
        while (itr.hasNext()){
            entry = (Entry) itr.next();
            key = (CFQRequestKey) entry.getKey();
            if ((Main.cabezal * numPistas - key.bloque) < min){
                min = (Main.cabezal * numPistas - key.bloque);
                auxKey = key;                
            }

        }
        return (CFQRequest) listaCFQRequest.remove(key);
    }

    /*
     * Coloca un cfqRequest en esta cola
     * 
     */
    public synchronized void put(CFQRequest request) {  
        
  
        listaCFQRequest.put(request.getKey(), request);
        count ++;        
        n++;
//        System.out.println("Recibe");
        //if (count == 1) {
            notifyAll();
        //}
    }
    
    public boolean isEmpty() {
        return listaCFQRequest.isEmpty();
    }
    
    public int getCount() {
        return count;
    }
    
    @Override
    public String toString() {
        String str = "" + prioridad;        
        return str;
    }
}

/*
 * 
 * 
 * 
 * 
 * prioridad: un entero  positivo que especifique la prioridad asociada a la cola. De 0 a 7 sería Real Time, de 8 a 15 Best Effort, 16 Idle y de 17 en adelante para identificar a las colas síncronas.
lista_peticiones: una lista con todas las cfq_request de la cola.
slice_idle: tiempo que se espera para que una cola actual adquiera una nueva operación de I/O antes de pasar a la siguiente cola.
slice: tiempo que tiene la cola en cada ronda para ser procesada.
 * 
 * 
 * 
 * 
 */
